// 监听token有值, 组件挂载后(某对象为空 || 强制回调) 某方法
// option 可是是布尔值,Number,Array,数组内装的是权限列表

import {isFunction, isArray, isEmpty, isNumber, isBoolean, isObject, isString, hasIn, difference} from 'lodash'
import { mapState } from 'vuex'
import * as moment from 'moment'
import notify from '@/tools/notify'
import { UPLOAD_BASE_URL } from '@/config/const'
import validate from '../config/validate'
// let i = 0
const utils = {
  computed: {
    ...mapState({
      token: state => state.auth.token,
      authList: state => state.auth.authList,
      scrollTop: state => state.auth.scrollTop,
      userInfo: state => state.user.info
    }),
    vali () {
      return validate
    },
    // 当前路由
    thisRoute () {
      return this.$route.path
    },
    thisRouteName () {
      return this.$route.name
    }
  },
  methods: {
    // 自动回调
    autoCallBack (obj, callback, option = false, unWatch = null) {
      // 如果token有效
      if (this.token.length === 32) {
        isFunction(callback) && (callback = [callback])
        if (!isArray(callback)) {
          alert('开发人员请注意::callback必需是回调函数或装有回调函数的数组')
          return
        }
        // 默认值
        let defaultOption = {
          // 当前角色需要全部具备以下权限才回调,false优先级第一
          authList: [],
          // 是否观察次数,false优先级第二
          coerce: false,
          // 默认调用几次,false优先级第三
          callTimes: 1,
          // 验证当前浏览器滚动条所处的位置是否大于某个值
          scrollTop: -1
        }
        if (isBoolean(option)) {
          defaultOption.coerce = option
          defaultOption.callTimes = 999999999
        } else if (isArray(option)) {
          defaultOption.authList = option
        } else if (isNumber(option)) {
          defaultOption.callTimes = option
          defaultOption.coerce = true
        } else if (isObject(option)) {
          defaultOption = {...defaultOption, ...option}
        } else {
          alert('开发人员请注意::option您传入了一个错误的参数类型')
          return
        }
        option = defaultOption
        // 如果被观察的对象为空或者不观察对象直接进行回调
        if (obj === true || isEmpty(obj) || (isArray(obj) && obj.length === 0)) {
          if (this.scrollTop < option.scrollTop) {
            isFunction(unWatch) && unWatch()
            return
          }
          if (option.coerce && option.callTimes < 1) {
            isFunction(unWatch) && unWatch()
            return
          }
          // 验证权限
          let newAuthList = difference(this.authList, option.authList)
          // false 代表没通过权限验证
          let judgeAuth = (this.authList.length - newAuthList.length) === option.authList.length
          if (!judgeAuth) {
            isFunction(unWatch) && unWatch()
            return
          }
          // 如果权限,观察次数验证通过
          option.coerce && (option.callTimes -= 1)
          for (let fun of callback) {
            fun()
          }
        }
      } else {
        let newUnWatch = this.$watch('token', function (val, oldVal) {
          this.autoCallBack(obj, callback, option, newUnWatch)
        })
      }
    },
    // 上传头像前的验证
    beforeAvatarUpload (file) {
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        notify.warning('上传头像图片只能是 JPG 或 PNG 格式!')
      }
      if (!isLt2M) {
        notify.warning('上传头像图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
    },
    // 如果用户不是在登录状态,跳到登录页
    jumpLogin () {
      if (isEmpty(this.userInfo)) {
        this.$router.push('/login')
      }
    },
    // 格式化时间
    momentFormat (time, format = 'YYYY-MM-DD') {
      return moment.unix(time).format(format)
    },
    // 原始moment
    moment (str) {
      return moment(str)
    },
    // 格式化价格的方法 分转成元展示
    priceFormat (penny, unit = '元', pre = false) {
      penny = Number(penny) || 0
      return pre && penny > 0
        ? pre + (penny / 100).toFixed(2) + unit
        : (penny / 100).toFixed(2) + unit
    },
    // 转绝结路径
    pathToAbs (relative, name = '') {
      return relative.indexOf('http') === -1
        ? UPLOAD_BASE_URL + relative + (name ? ('/' + name) : '')
        : relative + (name ? ('/' + name) : '')
    },
    // 用户的状态
    authStatus () {
      // -1 未提交 0 待审核 1 审核通过 2 审核失败
      if (isEmpty(this.userInfo) || !this.userInfo.other_info) {
        return {text: '未登录状态', actions: [], status: -2}
      }
      let text = '未知状态'
      let actions = []
      switch (Number(this.userInfo.other_info.authen_status)) {
        case -1:
        case '-1':
          text = '未提交'
          actions = [{action: 'submitAuth', str: '提交'}]
          break
        case 0:
        case '0':
          text = '待审核'
          actions = []
          break
        case 1:
        case '1':
          text = '审核通过'
          actions = []
          break
        case 2:
        case '2':
          text = '审核失败'
          actions = [{action: 'editAuth', str: '修改'}]
          break
        default:
          text = '未提交'
          actions = [{action: 'submitAuth', str: '提交'}]
      }
      // alert('status:' + JSON.stringify(this.userInfo.other_info) + ':' + text)
      return {text: text, actions: actions, status: Number(this.userInfo.other_info.authen_status)}
    },
    // 验证器vee-validate的再封装
    hasErr (name) {
      return this.errors.has(name) ? 'has-danger' : ''
    },
    showHasIn (obj, path = [], def = '', showLog = false, level = 0) {
      isString(path) && (path = path.split('.'))
      // 可以再完善下,用"0" || '0'的key代表字符串的key, 0代表数组的key
      // console.log('kkk:', obj, path, level)
      let oldLen = path.length
      let oldKey = path.shift()
      if (/^(['|"])[0-9]+\1$/.test(oldKey)) {
        oldKey = /[0-9]+/.exec(oldKey)[0]
      }
      // key值是弱类型,都可以理解为字符串,这里有点多余了..
      // else if (/^[0-9]+$/.test(oldKey)) {
      //   oldKey = Number(oldKey)
      // }
      if (hasIn(obj, oldKey)) {
        if (oldLen === 1) {
          return obj[oldKey]
        } else {
          return this.showHasIn(obj[oldKey], path, def, showLog, ++level)
        }
      } else {
        showLog && console.log('showHasIn方法使用了默认值', obj, path, def, level)
        return def
      }
    }
  }
}

export default utils
